Passed
Branchmaster (b37094)
by Plamen
01:25
created

table.js ➔ tablesLoadData   A

Complexity

Conditions 5
Paths 3

Size

Total Lines 20
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 6
Bugs 1 Features 1
Metric Value
cc 5
eloc 10
c 6
b 1
f 1
nc 3
nop 0
dl 0
loc 20
rs 9.3333
1
var strAsc = String.fromCharCode(9650); //▲
2
var strDesc = String.fromCharCode(9660);//▼
3
var xmlhttp;
4
var d;
5
6
var table = new function(){
7
    this.rq = null;
8
    this.tail = [];
9
10
    this.ReloadData = function(tableId){
11
        var request = {};
12
        this.BuildRequest(request, tableId);
13
        this.LoadData(tableId, request);
14
    };
15
16
    this.BuildRequest = function(request, crntTableId, skipPropertyArray){
17
        this.rq = request;
18
        this.checkSkip = function(skipProperty){
19
            var result = false;
20
            if(skipPropertyArray && Object.prototype.toString
21
                    .call(skipPropertyArray) === '[object Array]'
22
                    ){
23
                if(skipPropertyArray.indexOf(skipProperty) >= 0){
24
                    result = true;
25
                }
26
            }
27
            return result;
28
        };
29
        this.getSort = function(){
30
            var thTags = document.getElementById(crntTableId)
31
                    .getElementsByTagName("thead")[0]
32
                    .getElementsByTagName("th");
33
            var length = thTags.length;
34
            for(var i = 0; i < length; i++){
35
                var link = thTags[i].getElementsByTagName("a")[0];
36
                if(link && link.getElementsByTagName("span").length === 1){
37
                    var order = link.getElementsByTagName("span")[0].innerHTML;
38
                    if(order.length === 1){
39
                        this.rq.colNo = i;
40
                        this.rq.colOrd = (order === window.strDesc) ?
41
                                "desc" : "asc";
42
                    }
43
                }
44
            }
45
        };
46
        this.getFilter = function(){
47
            var r = this.getFilterFieldsByTbaleID(crntTableId);
48
            if(r.filter !== null){
49
                this.rq.filter = r.filter;
50
            }
51
            if(r.filterBy !== null){
52
                this.rq.filterBy = r.filterBy;
53
            }
54
        };
55
56
        /* Build request object */
57
        if(!this.checkSkip("sort")){
58
            this.getSort();
59
        }
60
        if(!this.checkSkip("filter")){
61
            this.getFilter();
62
        }
63
64
        this.rq.tableId = crntTableId;
65
        return this.rq;
66
    };
67
68
    this.RequestToUrl = function(rq){
69
        var url = location.pathname + ".json" + location.search;
70
        if(typeof rq === "object"){
71
            var getUrlVarName = {
72
                colNo: "col", colOrd: "ord", filter: "filter",
73
                filterBy: "filter-by", pageNo: "pg", exportType: "export",
74
                tableId: "table-id"
75
            };
76
            var flagFirst = location.search.length < 1 ? true : false;
77
            for(var r in rq){
1 ignored issue
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
78
                var clue = flagFirst === true ? "?" : "&";
79
                url += clue + getUrlVarName[r] + "=" + rq[r];
80
                flagFirst = false;
81
            }
82
        }
83
        return url;
84
    };
85
86
    this.Filter = function(field){
87
        var crntTableId = this.FilterGetTableId(field);
88
        if(crntTableId !== null){
89
            var request = {};
90
            var exRq = this.rq;
91
            this.BuildRequest(request, crntTableId);
92
            if(exRq === null ||
93
                    request.filter !== exRq.filter ||
94
                    request.filterBy !== exRq.filterBy
95
                    ){
96
                this.LoadData(crntTableId, request);
97
            }
98
        }
99
    };
100
101
    this.FilterGetTableId = function(field){
102
        if(field.tagName.toLowerCase() !== "select"){
103
            return field.getAttribute("data-table-id");
104
        }else{
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
105
            var f = field.parentNode.parentNode.getElementsByTagName("input")[0];
106
            return '' === f.value ? null : f.getAttribute("data-table-id");
107
        }
108
    };
109
110
    this.GoPage = function(lnk){
111
        var request = {};
112
        var table = this.getParent(lnk, "table");
113
        var crntTableId = table.getAttribute("id");
114
        this.BuildRequest(request, crntTableId);
115
        //check & serve pagination jump links
116
        var jumpDir = lnk.innerHTML.trim().substr(0, 1);
117
        if(jumpDir === "+" || jumpDir === "-"){
118
            var current = table.querySelector("tfoot .paging .a").innerHTML;
119
            var jump = lnk.innerHTML.replace("K", "000").replace("M", "000000000");
120
            var jumpPage = (parseInt(current) + parseInt(jump));
121
            lnk.parentNode.setAttribute("data-page", jumpPage);
122
            lnk.style.transform = "none";
123
        }
124
        request.pageNo = lnk.parentNode.hasAttribute("data-page") ?
125
                lnk.parentNode.getAttribute("data-page") :
126
                lnk.innerHTML;
127
        this.LoadData(crntTableId, request);
128
        return false;
129
    };
130
131
    this.Export = function(lnk, eType){
132
        var request = {};
133
        var crntTableId = this.getParent(lnk, "table").getAttribute("id");
134
        this.BuildRequest(request, crntTableId);
135
        request.exportType = ["CSV", "Excel"].indexOf(eType) >= 0 ? eType : "csv";
136
        window.open(this.RequestToUrl(request));
137
        return false;
138
    };
139
140
    this.Sort = function(colNo, lnk){
141
        var request = {};
142
        var crntTableId = this.getParent(lnk, "table").getAttribute("id");
143
        this.BuildRequest(request, crntTableId);
144
        if(Math.round(colNo) === request.colNo){
145
            request.colOrd = request.colOrd === "asc" ? "desc" : "asc";
146
        }else{
147
            request.colNo = Math.round(colNo);
148
            request.colOrd = "asc";
149
        }
150
        this.LoadData(crntTableId, request);
151
        /* Clear and add new sort arrow */
152
        var headSpans = this.getParent(lnk, "thead").getElementsByTagName("span");
153
        var length = headSpans.length;
154
        for(var i = 0; i < length; i++){
155
            headSpans[i].innerHTML = "";
156
        }
157
        lnk.getElementsByTagName("span")[0].innerHTML = (request.colOrd === "desc" ? window.strDesc : window.strAsc);
158
    };
159
160
    this.DrawSection = function(tableContainer, dt, tSection){
161
        var section = tSection === "tfoot" ? "tfoot" : "tbody";
162
        tSection = document.getElementById(tableContainer).
163
                getElementsByTagName(section)[0];
164
        this.clearSection(tSection);
165
        for(var i = 0; i < dt.length; i++){
166
            var row = dt[i];
167
            var tRow = document.createElement("tr");
168
169
            this.DrawRow(row, tRow);
170
171
            tSection.appendChild(tRow);
172
            if(section === "tfoot"){
173
                this.footerProcessPaginationLinks(tSection);
174
            }
175
            this.AppendRowCalback(tableContainer);
176
        }
177
    };
178
179
    this.DrawRow = function(row, tRow){
180
        for(var cell in row){
1 ignored issue
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
181
            var tCell = document.createElement("td");
182
            if(typeof row[cell] === "string" || typeof row[cell] === "number"){
183
                tCell.innerHTML = row[cell];
184
            }else if(typeof row[cell] === "object"){
185
                this.DrawCellFromObject(row, cell, tCell);
186
            }
187
            tRow.appendChild(tCell);
188
        }
189
    };
190
191
    this.DrawCellFromObject = function(row, cell, tCell){
192
        for(var attr in row[cell]){
1 ignored issue
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
193
            if(typeof row[cell][attr] === "string"){
194
                tCell.innerHTML = row[cell][attr];
195
            }else if(typeof row[cell][attr] === "object"){
196
                for(var v in row[cell][attr]){
1 ignored issue
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
197
                    tCell.setAttribute(v, row[cell][attr][v]);
198
                }
199
            }
200
        }
201
    };
202
203
    this.footerProcessPaginationLinks = function(tSection){
204
        var pLinks = tSection.querySelectorAll(".paging a");
205
        if(pLinks.length > 0){
206
            for(var j = 0; j < pLinks.length; j++){
207
                pLinks[j].setAttribute("href", "javascript:void(0);");
208
                pLinks[j].setAttribute("onclick", "return table.GoPage(this);");
209
            }
210
        }
211
    };
212
213
    this.clearSection = function(tSection){
214
        if(this.iePrior(9)){
215
            if(tSection.firstChild){
216
                while(tSection.firstChild){
217
                    tSection.removeChild(tSection.firstChild);
218
                }
219
            }
220
        }else{
221
            tSection.innerHTML = "";
222
        }
223
    };
224
225
    this.SetTheTableColumnsHoverEffect = function(tableContainer){
226
        if(this.iePrior(9)){
227
            return;
228
        }
229
        var tContainer = document.getElementById(tableContainer);
230
        var tHcells = tContainer.rows[0].cells;
231
        for(var i = 0; i < tHcells.length; i++){
232
            if(tHcells[i].firstChild.tagName === "A"){
233
                tHcells[i].firstChild.setAttribute("onmouseover", "table.ColumnHover('" + tableContainer + "'," + i + ");");
234
                tHcells[i].firstChild.setAttribute("onmouseout", "table.ColumnHover('" + tableContainer + "');");
235
            }
236
        }
237
        this.setPagingLinksSetActions(tContainer);
238
    };
239
240
    this.setPagingLinksSetActions = function(tContainer){
241
        var pLinks = tContainer.querySelectorAll("tfoot .paging a");
242
        if(pLinks.length > 0){
243
            for(var j = 0; j < pLinks.length; j++){
244
                pLinks[j].setAttribute("href", "javascript:void(0);");
245
                pLinks[j].setAttribute("onclick", "return table.GoPage(this);");
246
            }
247
        }
248
    };
249
250
    this.ColumnHover = function(tableContainer, index){
251
        if(!this.iePrior(9)){
252
            var tRow = document.getElementById(tableContainer).rows;
253
            index = Math.round(index);
254
            for(var i = 0; i < (tRow.length - 1); i++){
255
                if(index >= 0){
256
                    tRow[i].cells[index].setAttribute("lang", "col-hover");
257
                }else{
258
                    for(var j = 0; j < tRow[i].cells.length; j++){
259
                        if(tRow[i].cells[j].lang){
260
                            tRow[i].cells[j].removeAttribute("lang");
261
                        }
262
                    }
263
                }
264
            }
265
        }
266
    };
267
268
    this.getFilterFieldsByTbaleID = function(tableID){
269
        var fields = {filterBy: null, filter: null};
270
        var filterDiv = this.getFilterDivByTableIDOrNull(tableID);
271
        if(filterDiv !== null){
272
            var selectObj = filterDiv.getElementsByTagName("select")[0];
273
            var textObj = filterDiv.getElementsByTagName("input")[0];
274
            fields.filterBy = (selectObj === null || selectObj.options[selectObj.selectedIndex].value === "all") ? null : selectObj.options[selectObj.selectedIndex].value;
275
            fields.filter = (textObj === null || textObj.value.length === 0) ? null : encodeURIComponent(textObj.value.trim());
276
        }
277
        return fields;
278
    };
279
280
    this.getFilterDivByTableIDOrNull = function(tableID){
281
        var res = null;
282
        if(document.getElementById(tableID).parentNode.getElementsByTagName("div").length > 0){
283
            for(var i = 0; i < document.getElementById(tableID).parentNode.getElementsByTagName("div").length; i++){
284
                if(document.getElementById(tableID).parentNode.getElementsByTagName("div")[i].getAttribute("class") === "filter"){
285
                    return document.getElementById(tableID).parentNode.getElementsByTagName("div")[i];
286
                }
287
            }
288
289
        }
290
        return res;
291
    };
292
293
    this.LoadData = function(tableContainer, rq){
294
        this.setVisability(tableContainer, false);
295
        if(window.XMLHttpRequest){
296
            xmlhttp = new XMLHttpRequest();/* code for IE7+, Firefox, Chrome, Opera, Safari */
297
        }else{ /** global: ActiveXObject */
298
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");/*code for IE6, IE5 */
0 ignored issues
show
Bug introduced by
The variable ActiveXObject seems to be never declared. If this is a global, consider adding a /** global: ActiveXObject */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
299
        }
300
        for(var i = 0; i < this.tail.length; i++){
301
            var ex_xmlhttp = this.tail.shift();
302
            ex_xmlhttp.abort();
303
        }
304
        xmlhttp.onreadystatechange = function(){
305
            if(xmlhttp.readyState === 4 && xmlhttp.status === 200){
306
                d = JSON.parse(xmlhttp.responseText);
307
                table.DrawSection(tableContainer, d.body);
308
                table.DrawSection(tableContainer, d.footer, "tfoot");
309
                table.LoadEndCalback(tableContainer);
310
                table.setVisability(tableContainer, true);
311
                if(typeof rq === "object"){
312
                    table.ColumnHover(tableContainer, rq.colNo);
313
                }
314
            }
315
        };
316
        xmlhttp.open("GET", this.RequestToUrl(rq), true);
317
        xmlhttp.send();
318
        this.tail.push(xmlhttp); //put in tail to may later abort any previous
319
    };
320
321
    this.setVisability = function(tableContainer, rq){
322
        var tbl = document.getElementById(tableContainer);
323
        if(rq === true){
324
            tbl.style.filter = "none";
325
            tbl.style.opacity = "1";
326
            tbl.style.cursor = "auto";
327
        }else if(rq === false){
328
            tbl.style.filter = "blur(1px)";
329
            tbl.style.opacity = "0.8";
330
            tbl.style.cursor = "wait";
331
        }else{
332
            console.log("table error in the rq value"); /*Shows error*/
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
333
        }
334
    };
335
336
    this.getParent = function(obj, objType){
337
        while(obj && obj.tagName !== objType.toUpperCase()){
338
            obj = obj.parentNode;
339
        }
340
        return obj;
341
    };
342
343
    this.init = function(tableId){
344
        this.SetTheTableColumnsHoverEffect(tableId);
345
    };
346
347
    this.iePrior = function(v){
348
        var rv = false;
349
        if(/** global: navigator */ navigator.appName === 'Microsoft Internet Explorer'){
0 ignored issues
show
Bug introduced by
The variable navigator seems to be never declared. If this is a global, consider adding a /** global: navigator */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
350
            var ua = navigator.userAgent;
351
            var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
352
            if(re.exec(ua) !== null){
353
                rv = parseFloat(RegExp.$1);
354
            }
355
            rv = rv < v ? true : false;
356
        }
357
        return rv;
358
    };
359
    this.loadJS = function(src){
360
        var s = document.createElement('script');
361
        s.src = src;
362
        document.getElementsByTagName('head')[0].appendChild(s);
363
    };
364
    this.loadCSS = function(src){
365
        var s = document.createElement('link');
366
        s.href = src;
367
        s.rel = "stylesheet";
368
        document.getElementsByTagName('head')[0].appendChild(s);
369
    };
370
371
    this.LoadEndCalback = function(tableId){
372
        if(tableId){/*Allows override*/
0 ignored issues
show
Comprehensibility Documentation Best Practice introduced by
This code block is empty. Consider removing it or adding a comment to explain.
Loading history...
373
        }
374
    };
375
    this.AppendRowCalback = function(tableId){
376
        if(tableId){/*Allows override*/
0 ignored issues
show
Comprehensibility Documentation Best Practice introduced by
This code block is empty. Consider removing it or adding a comment to explain.
Loading history...
377
        }
378
    };
379
};
380
381
/** Moves custom created filter to the Table's filter
382
 * @param {string} filterId
383
 * @param {string} tableId
384
 * @param {boolean} delay - needed in case the table is istill not executed */
385
function moveSelectorToTheTableFilter(filterId, tableId, delay){
386
    if(delay === true){
387
        setTimeout(function(){
388
            var filterDiv = document.getElementById(tableId)
389
                    .getElementsByTagName("div")[0];
390
            filterDiv.appendChild(document.getElementById(filterId));
391
        }, 500);
392
    }else{
393
        var filterDiv = document.getElementById(tableId)
394
                .getElementsByTagName("div")[0];
395
        filterDiv.appendChild(document.getElementById(filterId));
396
    }
397
}
398
function changeListCustomFilter(selectObj){
399
    var fId = selectObj.options[selectObj.selectedIndex].value;
400
    var hasValue = fId !== "{!--Empty--!}";
401
    var varName = selectObj.getAttribute("name");
402
    var varPos = (document.URL.indexOf(varName) - (hasValue ? 0 : 1));
403
    if(varPos > 0){
404
        var url = document.URL.substring(0, varPos);
405
    }else{
406
        var separator = document.URL.indexOf("?") > 0 ? "&" : "?";
407
        url = document.URL + (hasValue ? separator : "");
408
    }
409
    var newUrl = url + (hasValue ? (varName + "=" + fId) : "");
410
    location.assign(newUrl);
411
}
412
413
414
function tablesLoadData(){
415
    var tables = document.getElementsByTagName("table");
416
    var envPrior9 = table.iePrior(9);
417
    for(var i = 0; i < tables.length; i++){
418
        var isProcessable = envPrior9 ?
419
                            typeof tables[i]["data-table"] !== 'undefined' :
420
                            tables[i].hasAttribute("data-table");
421
        if(isProcessable && tables[i].getAttribute("data-table") === "js"){
422
            table.LoadData(tables[i].id);
423
            table.SetTheTableColumnsHoverEffect(tables[i].id);
424
        }
425
    }
426
    /*if(table.iePrior(10)){
427
        table.loadJS("/add/helpers/table/add/json2.js");
428
    }
429
430
    if(table.iePrior(8)){ //can be used to add apropriate tables links modifications
431
     // loadCSS("/add/helpers/table/add/ie7-and-down.css");
432
     }*/
433
}
434
435
/*if(window.addEventListener){window.addEventListener('load',tablesLoadData,false);} else if(window.attachEvent){window.attachEvent('onload',tablesLoadData);}*/